package com.woniu.ly.manageassembly.component;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.woniu.ly.manageassembly.dao.SeckillTourMapper;
import com.woniu.ly.manageassembly.model.info.UserSeckillInfo;
import com.woniu.ly.model.model.SeckillTour;
import io.reactivex.rxjava3.core.Single;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.*;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

@Component
@Slf4j
public class AdminSeckillComponent {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private SeckillTourMapper seckillTourMapper;

    //将当天能开启的秒杀团id存入缓存中
    //使用@Scheduled注解设置定时任务
    //@Scheduled(cron = "0 58 17 ? * *")
    public void addAllSeckillTourIdInRedis(){
        log.info("自动添加秒杀团功能已开启");
        //查询数据库，所有未开的秒杀团
        QueryWrapper<SeckillTour> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("tour_status","秒杀未开始");
        List<SeckillTour> tourList = seckillTourMapper.selectList(queryWrapper);
        ListOperations list = redisTemplate.opsForList();
        for (SeckillTour seckillTour : tourList) {

            Timestamp seckillStartTime = seckillTour.getSeckillStartTime();
            log.info("秒杀开启时间： {}",seckillStartTime);
            long startTime = seckillStartTime.getTime();
            long nowTime = new Date().getTime();
            long leadTime = (startTime-nowTime)/1000;
            log.info("时间差：{}",leadTime);
            if (leadTime < 3600 && leadTime > 0){
                list.leftPush("notStartSeckillTourId", seckillTour.getSeckillTourId());
            }
        }
        //设置缓存过期时间
        redisTemplate.expire("notStartSeckillTourId",90L,TimeUnit.MINUTES);
    }

    //开启秒杀的方法（每天晚上八点前一秒开启）
    //使用@Scheduled注解设置定时任务
    //@Scheduled(cron = "10 58 17 ? * *")
    public void startSeckill(){
        log.info("开始执行开启秒杀团的方法");
        ListOperations listOperations = redisTemplate.opsForList();
        //取出当天能开的所有秒杀团id
        Long size = listOperations.size("notStartSeckillTourId");
        log.info("秒杀团个数：{}",size);
        for (int i = 0; i <size ; i++) {
            Integer seckillTourId = (Integer)listOperations.index("notStartSeckillTourId",i);
            log.info("准备开启的秒杀团id：{}",seckillTourId);
            //将秒杀团名额设置到缓存，并初始化
            addSeckillTourById(seckillTourId);
            log.info("开启秒杀");
        }
    }

    //检查用户是否付款的方法
    //使用@Scheduled注解设置定时任务
    //@Scheduled(cron = "* 59 17 ? * *")
    public void checkUserPayOrNot(){
        try {
            TimeUnit.SECONDS.sleep(3L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        log.info("执行 checkUserPayOrNot 方法");
        ListOperations listOperations = redisTemplate.opsForList();
        Long size = listOperations.size("notStartSeckillTourId");
        for (int i = 0; i <size ; i++) {
            Integer seckillTourId = (Integer)listOperations.index("notStartSeckillTourId", i);
            selectPayStatus(seckillTourId);
        }
    }

    //设置秒杀团名额缓存
    public void addSeckillTourById(int seckillTourId){
        HashOperations operations = redisTemplate.opsForHash();
        //设置缓存初始值为0
        operations.put("SeckillSuccess"+seckillTourId,seckillTourId,0);
        //设置缓存过期时间
        redisTemplate.expire("SeckillSuccess"+seckillTourId,90L,TimeUnit.MINUTES);
        log.info("添加 {} 完成，初始化成功","SeckillSuccess"+seckillTourId);
    }

    //查询用户是否付款，如果未付款，则将抢购到的名额退回到缓存
    public void selectPayStatus(int seckillTourId){
        HashOperations<String, Object, Object> operations = redisTemplate.opsForHash();
        //遍历缓存
        Map successUserInfos = operations.entries("AfterSuccess"+seckillTourId);
        Set keySet = successUserInfos.keySet();
        //得到所有抢购成功的用户
        for(Object userKey:keySet){
            String key = (String)userKey;
            UserSeckillInfo userSeckillInfo = (UserSeckillInfo)successUserInfos.get(key);
            //判断是否超过付款时间
            if("no".equals(userSeckillInfo.getPayStuats())){
                long nowTime = new Date().getTime();
                long l = (nowTime - userSeckillInfo.getSuccessTime()) / 1000;
                if (l<60){
                    log.info("在支付时间内");
                }else {
                    log.info("超过支付时间");
                    //用户抢购成功的名额
                    int successNum = userSeckillInfo.getTravelNum();
                    //查询最新的抢购成功名额
                    int newSuccessNum = (Integer)operations.get("SeckillSuccess"+seckillTourId, seckillTourId);
                    //将名额退回到缓存
                    operations.put("SeckillSuccess"+seckillTourId,seckillTourId,newSuccessNum-successNum);
                    //删除用户的抢购成功信息
                    operations.delete("AfterSuccess"+seckillTourId,key);
                    //查询退回后的抢购成功名额
                    int AfterRollBackSuccessNum = (Integer)operations.get("SeckillSuccess"+seckillTourId, seckillTourId);
                    log.info("该用户的抢购名额:{} ，剩余成功的抢购名额:{}",successNum,AfterRollBackSuccessNum);
                }
            }
        }
    }


}
